#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/kthread.h>
#include <linux/delay.h>

#define PCPU_COUNT 65535

static void __percpu *pcpu_var[PCPU_COUNT];
static int idx;
static struct task_struct *tsk;

static void clean_pcpu(void)
{
	int i;

	for (i = 0; i < PCPU_COUNT; i++) {
		if (pcpu_var[i] == NULL)
			continue;
		free_percpu(pcpu_var[i]);
	}
}

static int my_thread_fn(void *data)
{
	while (!kthread_should_stop()) {
		pcpu_var[idx] = alloc_percpu(unsigned long);
		if (!pcpu_var[idx]) {
			pr_err("alloc_percpu %d failed\n", idx);
		} else {
			//pr_err("alloc_percpu %d success\n", idx);
			idx++;
		}
		ssleep(1);
	}

	return 0;
}

static int __init pcpu_init(void)
{
	tsk = kthread_run(my_thread_fn, NULL, "mytsk");
	if (!tsk) {
		pr_err("create mytsk failed\n");
		return -ENOMEM;
	}

	return 0;
}

static void __exit pcpu_exit(void)
{
	if (tsk)
		kthread_stop(tsk);

	clean_pcpu();
}

module_init(pcpu_init);
module_exit(pcpu_exit);
MODULE_LICENSE("GPL");
